#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>

#include <memoriaI.h>
#include <semaforoI.h>
#include <global.h>

#define MUTEX "mutex"
#define BUFFER "buffer"

#define PRODUCTORES 5
#define CONSUMIDORES 5

void esperar (int senhal);
void controlador (int senhal);

int main (int argc, char *argv[]) {
  int pid_hijo;
  int i = 0;
  srand((int)getpid());

  crear_var(BUFFER, 10);
  crear_sem(MUTEX, 1);

  // Se lanzan los productores...
  for (i = 0; i < PRODUCTORES; i++)
    switch (pid_hijo = fork()) {
    case 0:
      execl("./exec/productor", "productor", NULL);
      break;
    }

  // Se lanzan los consumidores...
  for (i = 0; i < CONSUMIDORES; i++)
    switch (pid_hijo = fork()) {
    case 0:
      execl("./exec/consumidor", "consumidor", NULL);
      break;
    }

  // Se espera la terminación de los procesos...
  if (signal(SIGCHLD, esperar) == SIG_ERR) {
    fprintf(stderr, "No se esperó a un proceso.\n");
    exit(1);
  }

  // Manejo de Ctrol+C.
  if (signal(SIGINT, controlador) == SIG_ERR) {
    fprintf(stderr, "Terminación incorrecta.\n");
    exit(1);
  }

  while(1) // Bucle infinito de espera.
    pause(); // A la espera de Ctrol+C.

  return 0;
}

void esperar (int senhal) {
  int i;
  while (wait3(&i, WNOHANG, NULL) > 0);
}

void controlador (int senhal) {
  printf("\nCtrl+c capturada.\n");
  printf("Finalizando...\n\n");

  // Destrucción de variables.
  destruir_var(BUFFER);
  // Destrucción de semáforos.
  destruir_sem(MUTEX);

  sleep(1);
  printf("OK!\n");
  // Salida del programa.
  exit(0);
}
